﻿using EasyFileSync.Core.Entity;
using EasyFileSync.Core.Enums;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace EasyFileSync.Core.Config
{
    public class SyncConfig
    {
        public List<JobConfig> Jobs { get; set; } = new List<JobConfig>();

        public void Load(string path)
        {
            if (!File.Exists(path))
                throw new Exception($"配置文件不存在：{path}");

            var xmlDoc = new XmlDocument();
            xmlDoc.Load(path);
            var root = xmlDoc.SelectSingleNode("config");
            var ftps = root.SelectSingleNode("ftps").SelectNodes("ftp");
            var dict = new Dictionary<string, FtpConfig>();
            foreach (XmlNode ftp in ftps)
            {
                var name = ftp.Attributes["name"]?.Value;
                var config = new FtpConfig
                {
                    Name = name,
                    Host = ftp.Attributes["host"]?.Value,
                    User = ftp.Attributes["user"]?.Value,
                    Pass = ftp.Attributes["pass"]?.Value
                };
                dict.Add(name, config);
            }

            var jobs = root.SelectSingleNode("jobs").SelectNodes("job");
            foreach (XmlNode job in jobs)
            {
                if (int.TryParse(job.Attributes["disable"]?.Value, out int disable) && disable == 1)
                    continue;

                var config = new JobConfig
                {
                    Name = job.Attributes["name"]?.Value
                };

                if (int.TryParse(job.Attributes["type"]?.Value, out int type))
                    config.Type = (SyncType)type;

                if (int.TryParse(job.Attributes["mode"]?.Value, out int mode))
                    config.Mode = (SyncMode)mode;

                if (int.TryParse(job.Attributes["strategy"]?.Value, out int strategy))
                    config.Strategy = (SyncStrategy)strategy;

                var fromNode = job.SelectSingleNode("from");
                var toNode = job.SelectSingleNode("to");

                switch (config.Type)
                {
                    case SyncType.LocalToLocal:
                        config.From = new NTFSDir(fromNode.InnerText);
                        config.To = new NTFSDir(toNode.InnerText);
                        break;
                    case SyncType.LocalToFtp:
                        config.From = new NTFSDir(fromNode.InnerText);
                        config.To = new FtpDir(dict[toNode.Attributes["ftp"]?.Value], toNode.InnerText);
                        break;
                    case SyncType.FtpToLocal:
                        config.From = new FtpDir(dict[fromNode.Attributes["ftp"]?.Value], fromNode.InnerText);
                        config.To = new NTFSDir(toNode.InnerText);
                        break;
                    case SyncType.FtpToFtp:
                        throw new NotSupportedException($"经简单测试还不支持Ftp to Ftp模式，待后续更新。");
                        //config.From = new FtpDir(dict[fromNode.Attributes["ftp"]?.Value], fromNode.InnerText);
                        //config.To = new FtpDir(dict[toNode.Attributes["ftp"]?.Value], toNode.InnerText);
                        //break;
                }

                Jobs.Add(config);
            }
        }
    }

    public class JobConfig
    {
        public string Name { get; set; }
        public SyncType Type { get; set; } = SyncType.LocalToLocal;
        public SyncStrategy Strategy { get; set; } = SyncStrategy.Date;
        public SyncMode Mode { get; set; } = SyncMode.Mirror;
        public ISyncDir From { get; set; }
        public ISyncDir To { get; set; }
    }

    public class FtpConfig
    {
        public string Name { get; internal set; }
        public string Host { get; internal set; }
        public string User { get; internal set; }
        public string Pass { get; internal set; }
    }
}
